﻿using System;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Altairis.Web.UI.WebControls {

    /// <summary>
    /// This class represents DetailsView, which determines its mode based on if existing item is loaded or not. If item is empty, switches itself into Insert mode.
    /// </summary>
    public class AutoModeDetailsView : DetailsView {
        #region Configuration properties

        /// <summary>
        /// Gets or sets URL to redirect after "Cancel" command is performed.
        /// </summary>
        /// <value>The cancel redirect URL.</value>
        [Category("Redirect URLs"), UrlProperty(), Description("Gets or sets URL to redirect after \"Cancel\" command is performed.")]
        public string CancelRedirectUrl {
            get { return (string)this.ViewState["CancelRedirectUrl"]; }
            set { this.ViewState["CancelRedirectUrl"] = value; }
        }

        /// <summary>
        /// Gets or sets URL to redirect after one of Cancel, Delete, Update or Insert commands is performed. May be overriden by command-specific properties.
        /// </summary>
        /// <value>The default redirect URL.</value>
        [Category("Redirect URLs"), UrlProperty(), Description("Gets or sets URL to redirect after one of Cancel, Delete, Update or Insert commands is performed. May be overriden by command-specific properties.")]
        public string DefaultRedirectUrl {
            get { return (string)this.ViewState["DefaultRedirectUrl"]; }
            set { this.ViewState["DefaultRedirectUrl"] = value; }
        }

        /// <summary>
        /// Gets or sets URL to redirect after "Delete" command is performed.
        /// </summary>
        /// <value>The delete redirect URL.</value>
        [Category("Redirect URLs"), UrlProperty(), Description("Gets or sets URL to redirect after \"Delete\" command is performed.")]
        public string DeleteRedirectUrl {
            get { return (string)this.ViewState["DeleteRedirectUrl"]; }
            set { this.ViewState["DeleteRedirectUrl"] = value; }
        }

        /// <summary>
        /// Gets or sets the text shown in the header in Edit mode when no HeaderTemplate is defined.
        /// </summary>
        /// <value>The text shown in the header in Edit mode when no HeaderTemplate is defined.</value>
        [Category("Appearance"), Description("The text shown in the header in Edit mode when no HeaderTemplate is defined.")]
        public string EditHeaderText {
            get { return (string)this.ViewState["EditHeaderText"]; }
            set { this.ViewState["EditHeaderText"] = value; }
        }

        /// <summary>
        /// Gets or sets the page title in Edit mode.
        /// </summary>
        /// <value>The edit page title.</value>
        [Category("Page title"), Description("Gets or sets the page title in Edit mode.")]
        public string EditPageTitle {
            get { return (string)this.ViewState["EditPageTitle"]; }
            set { this.ViewState["EditPageTitle"] = value; }
        }

        /// <summary>
        /// Gets or sets text shown in the header in Insert mode when no HeaderTemplate is defined
        /// </summary>
        /// <value>The text shown in the header in Insert mode when no HeaderTemplate is defined.</value>
        [Category("Appearance"), Description("The text shown in the header in Insert mode when no HeaderTemplate is defined.")]
        public string InsertHeaderText {
            get { return (string)this.ViewState["InsertHeaderText"]; }
            set { this.ViewState["InsertHeaderText"] = value; }
        }

        /// <summary>
        /// Gets or sets the page title in Insert mode.
        /// </summary>
        /// <value>The insert page title.</value>
        [Category("Page title"), Description("Gets or sets the page title in Insert mode.")]
        public string InsertPageTitle {
            get { return (string)this.ViewState["InsertPageTitle"]; }
            set { this.ViewState["InsertPageTitle"] = value; }
        }

        /// <summary>
        /// Gets or sets URL to redirect after "Insert" command is performed.
        /// </summary>
        /// <value>The insert redirect URL.</value>
        [Category("Redirect URLs"), UrlProperty(), Description("Gets or sets URL to redirect after \"Insert\" command is performed.")]
        public string InsertRedirectUrl {
            get { return (string)this.ViewState["InsertRedirectUrl"]; }
            set { this.ViewState["InsertRedirectUrl"] = value; }
        }

        /// <summary>
        /// Gets or sets the text shown in the header in ReadOnly mode when no HeaderTemplate is defined.
        /// </summary>
        /// <value>The text shown in the header in ReadOnly mode when no HeaderTemplate is defined.</value>
        [Category("Appearance"), Description("The text shown in the header in ReadOnly mode when no HeaderTemplate is defined.")]
        public string ReadOnlyHeaderText {
            get { return (string)this.ViewState["ReadOnlyHeaderText"]; }
            set { this.ViewState["ReadOnlyHeaderText"] = value; }
        }

        /// <summary>
        /// Gets or sets the page title in ReadOnly mode.
        /// </summary>
        /// <value>The read only page title.</value>
        [Category("Page title"), Description("Gets or sets the page title in ReadOnly mode.")]
        public string ReadOnlyPageTitle {
            get { return (string)this.ViewState["ReadOnlyPageTitle"]; }
            set { this.ViewState["ReadOnlyPageTitle"] = value; }
        }

        /// <summary>
        /// Gets or sets URL to redirect after "Update" command is performed.
        /// </summary>
        /// <value>The update redirect URL.</value>
        [Category("Redirect URLs"), UrlProperty(), Description("Gets or sets URL to redirect after \"Update\" command is performed.")]
        public string UpdateRedirectUrl {
            get { return (string)this.ViewState["UpdateRedirectUrl"]; }
            set { this.ViewState["UpdateRedirectUrl"] = value; }
        }

        #endregion Configuration properties

        /// <summary>
        /// Initializes a new instance of the <see cref="AutoModeDetailsView"/> class.
        /// </summary>
        public AutoModeDetailsView() {
            // Hook up the relevant events
            this.ItemCreated += new EventHandler(AutoModeDetailsView_ItemCreated);
            this.ItemCommand += new DetailsViewCommandEventHandler(AutoModeDetailsView_ItemCommand);
            this.ItemInserted += new DetailsViewInsertedEventHandler(AutoModeDetailsView_ItemInserted);
            this.ItemUpdated += new DetailsViewUpdatedEventHandler(AutoModeDetailsView_ItemUpdated);
            this.ItemDeleted += new DetailsViewDeletedEventHandler(AutoModeDetailsView_ItemDeleted);
            this.Load += new EventHandler(AutoModeDetailsView_Load);
        }

        /// <summary>
        /// Handles the ItemCommand event of the AutoModeDetailsView control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.DetailsViewCommandEventArgs"/> instance containing the event data.</param>
        private void AutoModeDetailsView_ItemCommand(object sender, DetailsViewCommandEventArgs e) {
            if (e.CommandName.Equals("Cancel", StringComparison.OrdinalIgnoreCase)) {
                string redirectUrl = string.IsNullOrEmpty(this.CancelRedirectUrl) ? this.DefaultRedirectUrl : this.CancelRedirectUrl;
                if (!string.IsNullOrEmpty(redirectUrl)) this.Page.Response.Redirect(redirectUrl, false);
            }
        }

        /// <summary>
        /// Handles the ItemCreated event of the AutoModeDetailsView control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void AutoModeDetailsView_ItemCreated(object sender, EventArgs e) {
            if (this.DataItem == null && !this.Page.IsPostBack) this.ChangeMode(DetailsViewMode.Insert);
            this.UpdateTexts();
        }

        /// <summary>
        /// Handles the ItemDeleted event of the AutoModeDetailsView control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.DetailsViewDeletedEventArgs"/> instance containing the event data.</param>
        private void AutoModeDetailsView_ItemDeleted(object sender, DetailsViewDeletedEventArgs e) {
            string redirectUrl = string.IsNullOrEmpty(this.DeleteRedirectUrl) ? this.DefaultRedirectUrl : this.DeleteRedirectUrl;
            if (!string.IsNullOrEmpty(redirectUrl)) {
                if (e.Exception != null) throw e.Exception;
                this.Page.Response.Redirect(redirectUrl, false);
            }
        }

        /// <summary>
        /// Handles the ItemInserted event of the AutoModeDetailsView control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.DetailsViewInsertedEventArgs"/> instance containing the event data.</param>
        private void AutoModeDetailsView_ItemInserted(object sender, DetailsViewInsertedEventArgs e) {
            string redirectUrl = string.IsNullOrEmpty(this.InsertRedirectUrl) ? this.DefaultRedirectUrl : this.InsertRedirectUrl;
            if (!string.IsNullOrEmpty(redirectUrl)) {
                if (e.Exception != null) throw e.Exception;
                this.Page.Response.Redirect(redirectUrl, false);
            }
        }

        /// <summary>
        /// Handles the ItemUpdated event of the AutoModeDetailsView control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.DetailsViewUpdatedEventArgs"/> instance containing the event data.</param>
        private void AutoModeDetailsView_ItemUpdated(object sender, DetailsViewUpdatedEventArgs e) {
            string redirectUrl = string.IsNullOrEmpty(this.UpdateRedirectUrl) ? this.DefaultRedirectUrl : this.UpdateRedirectUrl;
            if (!string.IsNullOrEmpty(redirectUrl)) {
                if (e.Exception != null) throw e.Exception;
                this.Page.Response.Redirect(redirectUrl, false);
            }
        }

        /// <summary>
        /// Handles the Load event of the AutoModeDetailsView control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void AutoModeDetailsView_Load(object sender, EventArgs e) {
            this.UpdateTexts();
        }

        private void UpdateTexts() {
            if (this.DesignMode) return;
            switch (this.CurrentMode) {
                case DetailsViewMode.Edit:
                    if (!string.IsNullOrEmpty(this.EditPageTitle)) this.Page.Title = this.EditPageTitle;
                    if (!string.IsNullOrEmpty(this.EditHeaderText)) this.HeaderText = this.EditHeaderText;
                    break;

                case DetailsViewMode.Insert:
                    if (!string.IsNullOrEmpty(this.InsertPageTitle)) this.Page.Title = this.InsertPageTitle;
                    if (!string.IsNullOrEmpty(this.InsertHeaderText)) this.HeaderText = this.InsertHeaderText;
                    break;

                case DetailsViewMode.ReadOnly:
                    if (!string.IsNullOrEmpty(this.ReadOnlyPageTitle)) this.Page.Title = this.ReadOnlyPageTitle;
                    if (!string.IsNullOrEmpty(this.ReadOnlyHeaderText)) this.HeaderText = this.ReadOnlyHeaderText;
                    break;
                default:
                    break;
            }
        }
    }
}